package com.ce.webframework.i18n;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForward;

/**
 *
 * 功能描述：进行页面与组件国际化类
 *
 * @author 贺帅彪
 * @create date : 2007-8-30
 */
public class MessageLocale {
	/**
	 * 日志对象.
	 */
	protected final Logger logger = Logger.getLogger(getClass());

	/**
	 * @see javax.servlet.http.HttpServletRequest
	 */
	private HttpServletRequest request;

	/**
	 * @see javax.servlet.http.HttpServlet
	 */
	private HttpServlet servlet;

	/**
	 * @see org.apache.struts.action.ActionForward
	 */
	private ActionForward forward;

	/**
	 * 默认的国际化字符串，在web.xml设置，支持多个默认配置,用;隔开
	 */
	private String defaultLocaleStr;

	/**
	 * 当前国际化字符串
	 */
	private String localeStr;

	/**
	 * 页面国际化资源文件的cache
	 */
	private static Map<String, Properties> localMessageMap = new HashMap<String, Properties>();

	/**
	 * 全局国际化资源文件的cache
	 */
	private static Map<String, Properties> actionMessageMap = new HashMap<String, Properties>();

	/**
	 * 本类的构造函数
	 *
	 * @param request
	 * @param servlet
	 * @param forward
	 */
	public MessageLocale(HttpServletRequest request, HttpServlet servlet,
			ActionForward forward) {
		this.request = request;
		this.servlet = servlet;
		this.forward = forward;
	}

	/**
	 * 读取国际化资源文件
	 *
	 * @return 与页面对应的资源属性文件和全局资源属性文件
	 */
	public Properties getLocaleMessage() {

		if (servlet == null || forward == null || request == null) {
			return null;
		}
		Locale locale = request.getLocale();
		if (locale == null) {
			locale = Locale.getDefault();
		}
		localeStr = locale.toString();
		defaultLocaleStr = servlet.getInitParameter("defaultLocale");

		if (defaultLocaleStr == null) {
			defaultLocaleStr = "zh_CN";
		}
		String realPath = servlet.getServletContext().getRealPath("/");
		// String realPath = request.getRealPath("/");

		Properties resultProperties = getFullNameProperties(actionMessageMap,
				realPath, true);

		if (resultProperties == null) {
			resultProperties = getLanguageProperties(actionMessageMap,
					realPath, true);
			if (resultProperties == null) {
				resultProperties = getBaseNameProperties(actionMessageMap,
						realPath, true);
				if (resultProperties == null) {
					resultProperties = new Properties();
				}
			}
		}
		Properties actionProperties = getFullNameProperties(localMessageMap,
				realPath, false);

		if (actionProperties == null) {
			actionProperties = getLanguageProperties(localMessageMap, realPath,
					false);
			if (actionProperties == null) {
				actionProperties = getBaseNameProperties(localMessageMap,
						realPath, false);
				if (actionProperties == null) {
					actionProperties = new Properties();
				}
			}
		}
		resultProperties.putAll(actionProperties);

		return resultProperties;

	}

	/**
	 * 读取语言与国家后缀组成的国际化资源文件
	 *
	 * @param messageMap
	 *            对应的保存容器
	 * @param realPath
	 *            项目在WEB容器中的realPath
	 * @param isLoadActionMessage
	 *            叛断是取全局还是当前资料文件
	 * @return 封装好的资源属性文件
	 */
	private Properties getFullNameProperties(
			Map<String, Properties> messageMap, String realPath,
			boolean isLoadActionMessage) {

		StringBuilder filePath = null;
		if (isLoadActionMessage) {
			filePath = getActionFilePath(realPath);
		} else {
			filePath = getLocalFilePath(realPath);
		}
		if(filePath == null) {
			return null;
		}

		String filePathStr = filePath.toString();

		if (!messageMap.containsKey(filePathStr)) {
			if (!dealPath(messageMap, filePath)) {
				for (String localeTemp : defaultLocaleStr.split(";")) {
					// 当前国际化与默认国际化相同时，避免重复加载
					if (localeTemp.equals(localeStr)) {
						continue;
					}
					filePath = getDefaultFilePath(filePath, localeTemp);
					filePathStr = filePath.toString();
					// 默认国际化是否已经加载
					if (!messageMap.containsKey(filePathStr)) {
						// 加载成功退出循环
						if (dealPath(messageMap, filePath)) {
							break;
						}
					} else {
						break;
					}
				}
			}
		}

		// return messageMap.get(filePathStr) != null ? messageMap
		// .get(filePathStr) : new Properties();
		return messageMap.get(filePathStr);
	}

	/**
	 * 读取语言后缀组成的国际化资源文件
	 *
	 * @param messageMap
	 *            对应的保存容器
	 * @param realPath
	 *            项目在WEB容器中的realPath
	 * @param isLoadActionMessage
	 *            叛断是取全局还是当前资料文件
	 * @return 封装好的资源属性文件
	 */
	private Properties getLanguageProperties(
			Map<String, Properties> messageMap, String realPath,
			boolean isLoadActionMessage) {

		StringBuilder filePath = null;
		if (isLoadActionMessage) {
			filePath = getActionFilePath(realPath);
		} else {
			filePath = getLocalFilePath(realPath);
		}
		if(filePath == null) {
			return null;
		}

		int i = filePath.length() - 14;

		filePath = filePath.replace(i, i + 3, "");

		String filePathStr = filePath.toString();

		if (!messageMap.containsKey(filePathStr)) {
			if (!dealPath(messageMap, filePath)) {
				for (String localeTemp : defaultLocaleStr.split(";")) {
					// 当前国际化与默认国际化相同时，避免重复加载
					if (cutContrySuffix(localeTemp).equals(
							cutContrySuffix(localeStr))) {
						continue;
					}
					filePath = getCutDefaultFilePath(filePath,
							cutContrySuffix(localeTemp));
					filePathStr = filePath.toString();
					// 默认国际化是否已经加载
					if (!messageMap.containsKey(filePathStr)) {
						// 加载成功退出循环
						if (dealPath(messageMap, filePath)) {
							break;
						}
					} else {
						break;
					}
				}
			}
		}

		return messageMap.get(filePathStr);
	}

	/**
	 * 读取原名组成的国际化资源文件
	 *
	 * @param messageMap
	 *            对应的保存容器
	 * @param realPath
	 *            项目在WEB容器中的realPath
	 * @param isLoadActionMessage
	 *            叛断是取全局还是当前资料文件
	 * @return 封装好的资源属性文件
	 */
	private Properties getBaseNameProperties(
			Map<String, Properties> messageMap, String realPath,
			boolean isLoadActionMessage) {

		StringBuilder filePath = null;
		if (isLoadActionMessage) {
			filePath = getActionFilePath(realPath);
		} else {
			filePath = getLocalFilePath(realPath);
		}
		if(filePath == null) {
			return null;
		}
		// he_zh_CN.properties
		int i = filePath.length() - 16;
		// 把当前国际化文件路征替换成默认国际化的一种
		filePath = filePath.replace(i, i + 5, "");

		String filePathStr = filePath.toString();

		if (!messageMap.containsKey(filePathStr)) {
			dealPath(messageMap, filePath);
		}

		return messageMap.get(filePathStr);
	}

	/**
	 * 裁剪国家后缀名
	 *
	 * @param localeStr
	 * @return
	 */
	private String cutContrySuffix(String localeStr) {
		return localeStr.substring(0, localeStr.length() - 3);
	}

	/**
	 * 取得与输出页面对应的资源文件路征
	 *
	 * @param realPath
	 *            项目在WEB容器中的realPath
	 * @return 当前文件路征
	 */

	private StringBuilder getLocalFilePath(String realPath) {
		String path = forward.getPath();
		if (path.indexOf(".jsp") < 0) {
			return null;
		} else {
			path = path.replace(".jsp", "");
		}
		StringBuilder filePath = new StringBuilder().append(realPath).append(
				path).append("_").append(localeStr).append(".properties");
		return filePath;
	}

	/**
	 * 取得全局资源文件路征
	 *
	 * @param realPath
	 *            项目在容器中的realPath
	 * @return 全局文件路征
	 */
	private StringBuilder getActionFilePath(String realPath) {
		String servletName = servlet.getServletName();

		StringBuilder filePath = new StringBuilder().append(realPath).append(
				"WEB-INF/").append(servletName).append("_").append(localeStr)
				.append(".properties");
		return filePath;

	}

	/**
	 * 获取全称默认资源文件路征
	 *
	 * @param localFilePath
	 *            要替换的当前文件路征
	 * @return 替换后的路征
	 */
	private StringBuilder getDefaultFilePath(StringBuilder localFilePath,
			String replaceLocale) {
		// 取得字符串要修改的位置
		int i = localFilePath.length() - 16;
		// 把当前国际化文件路征替换成默认国际化的一种
		localFilePath = localFilePath.replace(i, i + 5, replaceLocale);
		return localFilePath;
	}

	/**
	 * 获取只包括语言默认资源文件路征
	 *
	 * @param localFilePath
	 *            要替换的当前文件路征
	 * @return 替换后的路征
	 */
	private StringBuilder getCutDefaultFilePath(StringBuilder localFilePath,
			String replaceLocale) {
		// 取得字符串要修改的位置
		int i = localFilePath.length() - 13;
		// 把当前国际化文件路征替换成默认国际化的一种
		localFilePath = localFilePath.replace(i, i + 2, replaceLocale);
		return localFilePath;
	}

	/**
	 * 加载资源属性文件，设入对应的cache
	 *
	 * @param map
	 *            资源文件要保存的容器
	 * @param filePath
	 *            文件路征
	 * @return 如果保存成功，返回true ,否则返回false
	 */
	private boolean dealPath(Map<String, Properties> map, StringBuilder filePath) {
		System.out
				.println("--------MessageLocale---------dealPath---filePath----: "
						+ filePath);
		Properties resultProperties = new Properties();
		InputStream is = getFileInputStream(filePath.toString());
		if (is == null) {
			return false;
		}
		try {
			resultProperties.load(is);
			is.close();
		} catch (IOException e) {
			logger.debug("--------------FileNotLoad: " + filePath);
			return false;
		}

		map.put(filePath.toString(), resultProperties);
		resultProperties = null;
		return true;
	}

	/**
	 * 取得文件输入流
	 *
	 * @param fileName
	 *            文件绝对路征
	 * @return 返回文件输入流,如果文件存在
	 */
	private InputStream getFileInputStream(String fileName) {

		File file = new File(fileName);
		if (file.exists()) {
			try {
				return new FileInputStream(file);
			} catch (FileNotFoundException e) {
				logger.debug("--------------FileNotFound: " + fileName);
				return null;
			}
		}

		return null;
	}
}
